/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.dbtools.tableditor;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

import jdbcmanager.swing.*;
import jdbcmanager.app.*;
import jdbcmanager.dbtools.*;
import jdbcmanager.dbtools.datatypes.*;

/**
 * A panel with a table containing all indices related with the table under edition.
 *
 * @author Francisco Morero Peyrona
 */
final class TabIndices extends JPanel
{
   private DbEntityDescriptor dedTable;   // Table which indices are associated to
   
   private JComboBox      cmbIndex;       // Indices related with selected table 
   private JxTableIndices tblIndex;       // Inf about selected index in the ComboBox
   
   //-------------------------------------------------------------------------//
   
   TabIndices( DbEntityDescriptor dedTable, IndexDefinition[] aIndex )
   {
      this.dedTable = dedTable;
      this.tblIndex = new JxTableIndices();
     
      init( aIndex );
   }

   IndexDefinition[] getIndices()
   {
      IndexDefinition[] aRet = new IndexDefinition[ this.cmbIndex.getItemCount() ];

      for( int n = 0; n < aRet.length; n++ )
         aRet[n] = (IndexDefinition) this.cmbIndex.getItemAt( n );
      
      return aRet;
   }
   
   boolean isCongruent()
   {
      IndexDefinition[] aIndex   = getIndices();
      boolean           bSuccess = true;
      
      for( int n = 0; n < aIndex.length; n++ )
      	bSuccess = bSuccess && DbUtil.getAgentDBMS().getAgentSQL().isValidIndex( aIndex[n] );
      
      return bSuccess;
   }
   
   //-------------------------------------------------------------------------//   
   
   /**
    * Updates table name and available column names.
    * <p>
    * This method is invoked everytime that this tab gets focus.
    *  
    * @param sNewName   New table name 
    * @param asColName  New column names
    */
   void updateInformation( String sNewName, String[] asColName )
   {      
      // update table name
      int nItems = this.cmbIndex.getItemCount();
      
      for( int n = 0; n < nItems; n++ )
         ((IndexDefinition) this.cmbIndex.getItemAt( n )).setTable( sNewName );
      
      // update table fields
      this.tblIndex.setAvailableColumNames( asColName );
   }
   
   //-------------------------------------------------------------------------//
   
   // Called when btnNew is clicked
   private void onNewIndex()
   {
      String sName = App.getStringUsingDialog( "Index creation", "New index name", "", false );
      
      if( sName != null )
      {
         sName = DbUtil.getAgentDBMS().getAgentSQL().normalizeDbEntityName( sName, DbEntityTypes.ENTITY_INDEX );
         
         if( sName.length() > 0 )
         {
            DbEntityDescriptor ded   = new DbEntityDescriptor( this.dedTable.getName(), this.dedTable.getCatalog(), sName );
            IndexDefinition    index = new IndexDefinition( ded, this.dedTable.getName() );
            this.cmbIndex.addItem( index );
         }
      }
   }
   
   // Called when btnDel is clicked
   private void onDelIndex()
   {
      int nIndex = this.cmbIndex.getSelectedIndex(); 
      
      if( nIndex > -1 && App.confirmDialog( "Delete confirmation", "Are you sure about to delete selected index?" ) )
         this.cmbIndex.removeItemAt( nIndex );   // See cmbIndex construction in this.init()
   }
   
   // Called when selected item changes in the ComboBox 
   private void onIndexSelection()
   {
      int nIndex = this.cmbIndex.getSelectedIndex();
      
      // Finish table editing: it is strictly necessary to be done
      if( this.tblIndex.isEditing() )
         this.tblIndex.editingCanceled( new ChangeEvent( this ) );
      
      if( nIndex > -1 )
      {
         IndexDefinition index = (IndexDefinition) this.cmbIndex.getItemAt( nIndex );
         
         this.tblIndex.setColumns( index.getColumns() );
      }
   }
   
   private void init( IndexDefinition[] aIndex )
   {      
      // Add + Del Buttons --------------------------------------
      JButton btnNewIndex = new JButton();
              btnNewIndex = new JButton( new ImageIcon( getClass().getResource( "images/new.gif" ) ) );
              btnNewIndex.setMargin( new Insets( 0, 0, 0, 0 ) );
              btnNewIndex.setToolTipText( "Create a new index" );
              btnNewIndex.addActionListener( new ActionListener()
              {
                 public void actionPerformed( ActionEvent evt )  { onNewIndex(); }
              } );
      
      JButton btnDelIndex = new JButton();
              btnDelIndex = new JButton( new ImageIcon( getClass().getResource( "images/delete.gif" ) ) );
              btnDelIndex.setMargin( new Insets( 0, 2, 0, 2 ) );
              btnDelIndex.setToolTipText( "Delete selected index" );
              btnDelIndex.addActionListener( new ActionListener()
              {
                 public void actionPerformed( ActionEvent evt )  { onDelIndex(); }
              } );
      
      // ComboBox -----------------------------------------------      
      this.cmbIndex = new JComboBox( aIndex );
      this.cmbIndex.setRenderer( new ComboIndexCellRenderer() );
      this.cmbIndex.addActionListener( new ActionListener()
      {
         public void actionPerformed( ActionEvent evt )  { onIndexSelection(); }
      } );
      
      if( aIndex.length > 0 )
         this.cmbIndex.setSelectedIndex( 0 );
      
      // ComboBox + Buttons  ------------------------------------
      JPanel pnlNorth = new JPanel( new SpringLayout() );
             pnlNorth.add( new JLabel( "Index" ) );
             pnlNorth.add( this.cmbIndex );
             pnlNorth.add( btnNewIndex );
             pnlNorth.add( btnDelIndex );
             pnlNorth.setBorder( BorderFactory.createEmptyBorder( 0,0,8,0 ) );
             SpringUtilities.makeCompactGrid( pnlNorth, 1, 4, 6, 6, 6, 6);
             
      // All together -------------------------------------------      
      setBorder( BorderFactory.createEmptyBorder( 8,8,8,8 ) );
      setLayout( new BorderLayout() );
      
      add( pnlNorth, BorderLayout.NORTH  );
      add( new JPanelParent( this.tblIndex ), BorderLayout.CENTER );
   }
   
   //-------------------------------------------------------------------------//
   // INNER CLASS: Cell Renderer for the Combo who holds available Indices
   //-------------------------------------------------------------------------//
   final class ComboIndexCellRenderer extends JLabel implements ListCellRenderer
   {
      ComboIndexCellRenderer()
      {
         setOpaque( true );
      }
      
      // This is the only method defined by ListCellRenderer.
      public Component getListCellRendererComponent( JList list,
                                                     Object value,        // value to display
                                                     int index,           // cell index
                                                     boolean bSelected,   // is the cell selected
                                                     boolean bHasFocus )  // the list and the cell have the focus
      {
         if( value == null )
            setText( "" );
         else
            setText( ((IndexDefinition) value).getName() );

         if( bSelected )
         {
            setBackground( list.getSelectionBackground() );
            setForeground( list.getSelectionForeground() );
         }
         else
         {
            setBackground( list.getBackground() );
            setForeground( list.getForeground() );
         }

         setEnabled( list.isEnabled() );

         return this;
      }
   }
}